package com.ankiang.treeprint.lib;

import android.content.Context;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ankiang.treeprint.model.TRItemNode;
import com.ankiang.treeprint.model.TRItemTree;
import com.ankiang.treeprint.model.TRGroupItem;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

public class TRDataManager {

    static final String TAG = "TRDataManager";
    static final String FILE_NAME_USER_FMT = "treeprint-%s.json";
    static final String FILE_NAME_SYS = "treeprint.json";
    private Context context;
    private static TRDataManager instance;

    JSONObject data;
    JSONObject dataSys;
    String currentUser = "default";

    public static TRDataManager getInstance(Context context) {
        if (instance == null) {
            instance = new TRDataManager();
        }
        if (context == null) {
            Log.e(TAG, "context == null");
        } else {
            instance.context = context;
        }
        return instance;
    }

    private TRDataManager() {

    }

    public void setCurrentUser(String currentUser) {
        this.currentUser = currentUser;
    }

    /**
     * 取配置
     *
     * @param key
     * @return
     */
    public String getConf(String key) {
        JSONObject conf = dataSys.getJSONObject("conf");
        if (conf == null) {
            return "";
        }
        String v = conf.getString(key);
        if (v == null) {
            return "";
        }
        return v;
    }

    /**
     * 某个节点下的菜单
     *
     * @param key
     * @return
     */
    public JSONArray getMenu(String key) {
        JSONArray v = dataSys.getJSONArray(key);
        if (v == null) {
            return new JSONArray();
        }

        // 找到这个节点的alias
        JSONArray res = new JSONArray();
        for (int i = 0; i < v.size(); i++) {
            JSONObject obj = v.getJSONObject(i);
            String palias = obj.getString("palias");
            if (palias.equals(key)) {
                res.add(obj);
            }
        }
        return res;
    }



    public TRItemTree getData(String group) {
        if (data == null) {
            Log.e(TAG, "data=null, group=" + group);
            return new TRItemTree();
        }
        JSONObject v = data.getJSONObject("data");
        if (v == null) {
            return new TRItemTree();
        }
        JSONArray list = v.getJSONArray(group);
        if (list == null) {
            return new TRItemTree();
        }
        TRItemTree tree = TRItemTree.convert(list);
        return tree;
    }

    /**
     * 数据分组列表
     *
     * @return
     */
    public JSONObject getGroupList() {
        if (data == null) {
            return new JSONObject();
        }
        JSONObject groups = data.getJSONObject("group");
        if (groups == null) {
            return new JSONObject();
        }
        return groups;
    }

    public void setData(int group, TRItemTree v){
        setData(String.valueOf(group),v);
    }

    public void setData(String group, TRItemTree v) {
        if (v == null) {
            return;
        }
        if (data == null) {
            data = new JSONObject();
        }

        JSONObject d = data.getJSONObject("data");
        if (d == null) {
            d = new JSONObject();
        }
        d.put(group, v.toJSONArray());
        data.put("data", d);

        // 如果没有这个数据，则新建一个
        JSONObject groupList = getGroupList();
        if (!groupList.keySet().contains(group)) {
            TRGroupItem item = new TRGroupItem();
            item.setId(Integer.parseInt(group));
            groupList.put(group, item);
        }
        this.data.put("group", groupList);
        this.save(); // 同时保存数据到磁盘
    }

    public TRItemTree getDefaultData() {
        String[][] v = {
                // id, fid, mid, callname, sex
                {"1", "0", "0", "爷爷", "M"},
                {"2", "0", "0", "奶奶", "F"},
                {"3", "1", "2", "爷爷+奶奶", "0"},
                {"4", "0", "0", "外公", "M"},
                {"5", "0", "0", "外婆", "F"},
                {"6", "4", "5", "外公+外婆", "0"},
                {"7", "3", "0", "大伯", "M"},
                {"8", "3", "0", "爸爸", "M"},
                {"9", "3", "0", "大姑", "F"},
                {"10", "6", "0", "大姨", "F"},
                {"11", "6", "0", "妈妈", "F"},
                {"12", "6", "0", "舅舅", "M"},
                {"13", "6", "0", "小姨", "F"},
                {"15", "0", "0", "大嫂", "F"},
                {"16", "14", "0", "大哥", "M"},
                {"17", "16", "15", "大哥+大嫂", "0"},
                {"18", "14", "0", "我", "M"},
                {"19", "14", "0", "三弟", "M"},
                {"14", "8", "11", "爸爸+妈妈", "0"},
                {"20", "17", "0", "侄子", "M"},
                {"21", "17", "0", "侄女", "F"},
                {"22", "0", "0", "侄媳妇", "F"},
                {"23", "20", "22", "侄子+侄媳妇", "0"},
                {"24", "23", "0", "侄孙", "M"},
                {"25", "0", "0", "舅妈", "F"},
                {"26", "0", "0", "大姨丈", "M"},
                {"27", "0", "0", "小姨丈", "M"},
                {"28", "0", "0", "大伯婶", "F"},
                {"29", "0", "0", "小叔婶", "F"},
                {"30", "12", "25", "舅舅+舅妈", "0"},
                {"32", "26", "10", "大姨+大姨丈", "0"},
                {"33", "27", "13", "小姨+小姨丈", "0"},
                {"34", "7", "28", "大伯+大伯婶", "0"},
                {"35", "36", "29", "小叔+小叔婶", "0"},
                {"36", "3", "0", "小叔", "M"},

                {"37", "0", "0", "大姑丈", "M"},
                {"38", "0", "0", "小姑丈", "M"},
                {"39", "38", "53", "小姑+小姑丈", "0"},
                {"40", "37", "9", "大姑+大姑丈", "0"},
                {"41", "34", "0", "堂哥", "M"},
                {"42", "0", "0", "堂嫂", "F"},
                {"43", "34", "0", "堂姐", "F"},
                {"44", "34", "0", "堂妹", "F"},
                {"45", "34", "0", "堂弟", "M"},
                {"46", "0", "0", "堂弟媳", "F"},
                {"47", "41", "42", "堂哥+堂嫂", "0"},
                {"48", "45", "46", "堂弟+堂弟媳", "0"},
                {"49", "0", "0", "堂妹夫", "M"},
                {"50", "0", "0", "堂姐夫", "M"},
                {"51", "50", "43", "堂姐夫+堂姐", "0"},
                {"52", "49", "44", "堂妹夫+堂妹", "0"},
                {"53", "34", "0", "小姑", "F"},

                {"54", "39", "0", "表哥", "M"},
                {"55", "0", "0", "表嫂", "F"},
                {"56", "54", "55", "表哥+表嫂", "0"},
                {"57", "39", "0", "表姐", "F"},
                {"58", "0", "0", "表姐夫", "M"},
                {"59", "58", "57", "表姐夫+表姐", "0"},
                {"60", "39", "0", "表弟", "M"},
                {"61", "0", "0", "表弟媳", "F"},
                {"62", "60", "61", "表弟+表弟媳", "0"},
                {"63", "39", "0", "表妹", "F"},
                {"64", "0", "0", "表妹夫", "M"},
                {"65", "64", "63", "表妹夫+表妹", "0"}




        };

        TRItemTree list = new TRItemTree();
        for (int i = 0; i < v.length; i++) {
            String[] line = v[i];
            for (int j = 0; j < line.length; j++) {
                TRItemNode item = new TRItemNode();
                int id = Integer.parseInt(line[0]);
                int fid = Integer.parseInt(line[1]);
                int mid = Integer.parseInt(line[2]);
                String callname = line[3];
                char sex = line[4].charAt(0);

                item.setCallname(callname);
                item.setId(id);
                item.setMid(mid);
                item.setFid(fid);
                item.setSex(sex);
                item.setRow(0);
                item.setColumn(0);
                item.setColor(0);
                item.setBornDateSun("2018-01-02");
                item.setBornDateMoon("2017-12-12");
                list.addItem(item);
            }
        }
        return list;
    }


    public void save() {
        if (data == null || data.isEmpty()) {
            Log.e(TAG, "save null data");
            return;
        }
        try {
            String fileName = getUserFileName();
            saveJSON(fileName, data);
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            e.printStackTrace();
        }

        try {
            if (dataSys != null) {
                saveJSON(FILE_NAME_SYS, dataSys);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
            return;
        }

    }

    private String getUserFileName() {
        return String.format(FILE_NAME_USER_FMT, currentUser);
    }


    public void load() {
        boolean needDemo = true;

        try {

            String fileName = getUserFileName();
            try {
                data = readJSON(fileName);
            } catch (Exception e) {
                e.printStackTrace();
                data = new JSONObject();
            }
            //Log.d(TAG + "/size/0", String.valueOf(getData("0").size()));

            try {
                dataSys = readJSON(FILE_NAME_SYS);
            } catch (Exception e) {
                e.printStackTrace();
                dataSys = new JSONObject();
            }

            // 之前没有保存过数据
            JSONObject groups = getGroupList();
            if (!groups.isEmpty()) {
                Log.i(TAG, groups.toJSONString());
                needDemo = false;
            }

        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
        if (needDemo) {
            TRItemTree tmp = getDefaultData();
            setData("0", tmp);
            TRGroupItem item = new TRGroupItem();
            item.setId(0);
            item.setName("大家族");
            setGroup(0, item);
        }
    }

    private JSONObject readJSON(String fileName) throws Exception {

        FileInputStream inStream = context.openFileInput(fileName);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = -1;

        while ((length = inStream.read(buffer)) != -1) {
            stream.write(buffer, 0, length);
        }

        stream.close();
        inStream.close();
        String json = stream.toString();

        Log.i(TAG + "/" + fileName, json);
        JSONObject jObj = JSON.parseObject(json);
        return jObj;

    }


    private void saveJSON(String fileName, JSONObject data) throws Exception {

        FileOutputStream outStream = this.context.openFileOutput(fileName, Context.MODE_PRIVATE);
        String s = data.toJSONString();
        Log.d(TAG + "/saving", s);
        outStream.write(s.getBytes());
        outStream.close();
        Log.i(TAG + "/fname", fileName);
    }

    public void setGroup(int nextId, TRGroupItem item) {
        JSONObject jobj = item.toJSONObject();
        data.getJSONObject("group").put(String.valueOf(nextId), jobj);
        save();
    }

    /**
     * 取得全部数据，用于查阅、导出等操作
     * @return
     */
    public JSONObject getAllData() {
        if(data == null){
            return new JSONObject();
        }
        return data;
    }

    public void deleteData(int group) {
        data.getJSONObject("group").remove(String.valueOf(group));
        data.getJSONObject("data").remove(String.valueOf(group));
        save();
    }

    public int getNextGroupId() {
        int max = 0;
        Iterator<String> iter = getGroupList().keySet().iterator();
        while(iter.hasNext()){
            int tmp = Integer.parseInt(iter.next());
            if(tmp > max){
                max = tmp;
            }
        }
        return max + 1;
    }

    public TRGroupItem getGroup(int itemId) {
        JSONObject item = getGroupList().getJSONObject(String.valueOf(itemId));
        return TRGroupItem.convert(item);
    }


    public JSONArray getConfigList() {
        return data.getJSONArray("conf");
    }
    public JSONArray getMenuList() {
        return data.getJSONArray("menu");
    }
}
